/**
 * 自定义坐标变换有ctx.transform(a, b, c, d, e, f) 和 ctx.setTransform(a, b, c, d, e, f) 两种实现方式
 * 区别是：
 *      transform函数多次调用的变换是叠加的，setTransform函数每次调用会清空前一次的变换
 * 相同点：
 *      他们都是控制变换矩阵实现自定义变化的
 * 
 * 通用坐标变换公式：
 *     x' = ax + cy + e;
 *     y' = bx + dy + f; 
 *      通过a~f六个参数取值组合可以实现平移、缩放、旋转、错切等变换
 * 
 * 1.平移
 *      x' = (1x + 0y + e) = (x + e); (a = 1, c = 0) 通过e 可以控制水平平移
 *      y' = (0x + 1y + f) = (y + f); (b = 0, d = 1) 通过f 可以控制竖直平移
 *      transform、setTransform(1, 0, 0, 1, 3, -5); 平移(+3, -5);
 * 
 * 2.缩放
 *      x' = (ax + 0y + 0) = ax; X轴方向上缩放倍数
 *      y' = (0x + dy + 0) = dy; Y轴方向上缩放倍数
 *      transform、setTransform(2, 0, 0, -1, 0, 0); X轴方向放大一倍、Y轴方向镜像
 * 
 * 3.旋转
 *      要转的角度 angle 度。
 *      x' = cos(angle)x - sin(angle)y + 0; 旋转 angle 度后x坐标
 *      y' = sin(angle)x + cos(angle)y + 0; 旋转 angle 度后y坐标
 *      假设要旋转30°，transform、setTransform(cos(30), sin(30), -sin(30), cos(30), 0, 0); 旋转30度
 * 
 * 4.错切
 *      根据变换公式，x' 依赖于 cy，y' 也依赖于 bx，故而，可以用b、c两个值来实现错切
 *      x' = (1x + cy + 0) = (x + cy); 于是x坐标在x轴方向上发生错位
 *      y' = (0x + 1y + 0) = y; y坐标不便
 *      此时的变换矩阵为 transform、setTransform(1, 0, .75, 1, 0, 0) 此时会向右错切
 * 
 * 联合调用：比如我们想要同时放大一倍、旋转30度、平移(10, -10);
 *  ctx.transform(2cos(30), sin(30), -sin(30), 2cos(30), 10, -10);
 */
var c = document.getElementById('c');
var ctx = c.getContext('2d');

ctx.save();
ctx.fillStyle = '#ddd';
ctx.fillRect(0, 0, c.width, c.height);
ctx.restore();

// 坐标变换
ctx.transform(1, 0, 0, 1, c.width / 2, c.height / 2);
// ctx.transform(-1, 0, 0, 1.5, 0, 0); //transform可叠加
// rotate(ctx, 45);
//斜切
ctx.transform(1, 0, .75, 1, 0, 0);

function rotate(ctx, deg) {
    var sin = Math.sin(degToRad(deg)), cos = Math.cos(degToRad(deg));
    ctx.transform(cos, sin, -sin, cos, 0, 0);

    function degToRad(deg) {
        return deg * Math.PI / 180;
    }
}

//绘制三角形
function drawCenterRect() {
    ctx.save();
    ctx.fillStyle = 'black';
    ctx.beginPath();
    ctx.moveTo(50, 0);
    ctx.lineTo(-25, 50);
    ctx.lineTo(-25, -50);
    ctx.closePath();
    ctx.fill();
    ctx.restore();
}
drawCenterRect();